﻿' ----------------------------------------------------------------------------------
' Microsoft Developer & Platform Evangelism
' 
' Copyright (c) Microsoft Corporation. All rights reserved.
' 
' THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
' EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
' OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ----------------------------------------------------------------------------------
' The example companies, organizations, products, domain names,
' e-mail addresses, logos, people, places, and events depicted
' herein are fictitious.  No association with any real company,
' organization, product, domain name, email address, logo, person,
' places, or events is intended or should be inferred.
' ----------------------------------------------------------------------------------

Imports Microsoft.WindowsAzure
Imports Microsoft.WindowsAzure.Diagnostics
Imports Microsoft.WindowsAzure.ServiceRuntime
Imports Microsoft.Samples.WindowsPhoneCloud.Web.Infrastructure
#If ACS Then
Imports System.Globalization
Imports System.Security.Permissions
Imports Microsoft.Web.Administration
#End If

Public Class WebRole
    Inherits RoleEntryPoint

    <System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification:="This method initializes the Web role.")>
    Public Overrides Function OnStart() As Boolean
        ' For information on handling configuration changes
        ' see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
        AddHandler RoleEnvironment.Changing, AddressOf RoleEnvironmentChanging

        ' This code sets up a handler to update CloudStorageAccount instances when their corresponding
        ' configuration settings change in the service configuration file.
        CloudStorageAccount.SetConfigurationSettingPublisher(Sub(configName, configSetter)
                                                                 ' Provide the configSetter with the initial value
                                                                 ' The corresponding configuration setting has changed, propagate the value
                                                                 ' In this case, the change to the storage account credentials in the
                                                                 ' service configuration is significant enough that the role needs to be
                                                                 ' recycled in order to use the latest settings. (for example, the 
                                                                 ' endpoint has changed)
                                                                 configSetter(RoleEnvironment.GetConfigurationSettingValue(configName))
                                                                 AddHandler RoleEnvironment.Changed, Sub(sender, arg)
                                                                                                         If arg.Changes.OfType(Of RoleEnvironmentConfigurationSettingChange)().Any(Function(change) (change.ConfigurationSettingName = configName)) Then
                                                                                                             If Not configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)) Then
                                                                                                                 RoleEnvironment.RequestRecycle()
                                                                                                             End If
                                                                                                         End If
                                                                                                     End Sub
                                                             End Sub)

#If ACS Then
        'If no valid WIF settings are found in the Web Role configuration, then the Web Role shouldn't start
        If (Not UpdateWifSettings()) Then
            Return False
        End If
#End If

        Return MyBase.OnStart()
    End Function

#If ACS Then
    <EnvironmentPermission(SecurityAction.LinkDemand)>
    Private Shared Function UpdateWifSettings() As Boolean
        Using server = New ServerManager()
            Dim siteNameFromServiceModel = "Web"
            Dim siteName = String.Format(CultureInfo.InvariantCulture, "{0}_{1}", RoleEnvironment.CurrentRoleInstance.Id, siteNameFromServiceModel)

            Dim configFilePath = String.Format(CultureInfo.InvariantCulture, "{0}\Web.config", server.Sites(siteName).Applications(0).VirtualDirectories(0).PhysicalPath)
            Dim xml = XElement.Load(configFilePath)
            Dim identityModelService = xml.Element("microsoft.identityModel").Element("service")

            If UpdateAttributeWithRoleSetting(identityModelService.Element("audienceUris").Element("add").Attribute("value"), "realm") AndAlso UpdateAttributeWithRoleSetting(identityModelService.Element("issuerTokenResolver").Element("serviceKeys").Element("add").Attribute("serviceName"), "realm") AndAlso UpdateAttributeWithRoleSetting(identityModelService.Element("issuerTokenResolver").Element("serviceKeys").Element("add").Attribute("serviceKey"), "serviceKey") AndAlso UpdateAttributeWithRoleSetting(identityModelService.Element("issuerNameRegistry").Element("trustedIssuers").Element("add").Attribute("issuerIdentifier"), "trustedIssuersIdentifier") AndAlso UpdateAttributeWithRoleSetting(identityModelService.Element("issuerNameRegistry").Element("trustedIssuers").Element("add").Attribute("name"), "trustedIssuerName") Then
                xml.Save(configFilePath)
                Return True
            End If

            Return False
        End Using
    End Function

    Private Shared Function UpdateAttributeWithRoleSetting(ByVal attribute As XAttribute, ByVal settingName As String) As Boolean
        Dim settingValue = ConfigReader.GetConfigValue(settingName, False)
        If Not String.IsNullOrEmpty(settingValue) Then
            attribute.Value = settingValue
        ElseIf String.IsNullOrEmpty(attribute.Value) Then
            Return False
        End If

        Return True
    End Function
#End If

    Private Sub RoleEnvironmentChanging(ByVal sender As Object, ByVal e As RoleEnvironmentChangingEventArgs)
        ' If a configuration setting is changing
        If e.Changes.Any(Function(change) TypeOf change Is RoleEnvironmentConfigurationSettingChange) Then
            ' Set e.Cancel to true to restart this role instance
            e.Cancel = True
        End If
    End Sub
End Class

